﻿using System;
using System.Collections.Generic;
using System.Security.Principal;
using UploadClient.Interfaces.Plugins;
using Microsoft.Win32;

namespace ContextmenuPlugin
{
    //ToDo: Localization!!!

    /// <summary>
    /// Adds or removes a entry to the contextmenu.
    /// </summary>
    public class Contextmenue : IPlugin
    {
        const string MenuName = "*\\shell\\NewMenuOption";
        const string Command = "*\\shell\\NewMenuOption\\command";
        Configurations config;
        IHost host;
        string path;
        string programName;

        #region IPlugin Members

        public void Init(IHost host)
        {
            config = new Configurations(host);
            programName = host.GetProgramName();
            path = host.GetExecutingAssemblyDirectoryName();
            this.host = host;
        }

        public void Init(IHost host, IPluginConfig settings)
        {
            Init(host);
            config = new Configurations(host, settings.Settings);
            if (settings.PluginEnabled) EnablePlugin();
        }

        public IEnumerable<IPluginConfig> GetConfiguration()
        {
            return new IPluginConfig[] { config };
        }

        public void EnablePlugin()
        {
            // enables contextmenu only if user has adminrights
            if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
            {
                config.PluginEnabled = true;
                if (!IsRegistryKeySet()) AddToConextmenue(host.GetLocalizationRessourceString("Upload..."), string.Format("{0}\\{1}", path, programName));
            }
        }

        public void DisablePlugin()
        {
            config.PluginEnabled = false;
            if (IsRegistryKeySet()) RemoveFromContextmenue();
        }

        #endregion

        /// <summary>
        /// Adds a entry to the contextmenu.
        /// </summary>
        /// <param name="name">The name of the entry.</param>
        /// <param name="path">The path to execute the program.</param>
        void AddToConextmenue(string name, string path)
        {
            RegistryKey regmenu = null;
            RegistryKey regcmd = null;
            try
            {
                regmenu = Registry.ClassesRoot.CreateSubKey(MenuName);
                if (regmenu != null)
                    regmenu.SetValue("", name);
                regcmd = Registry.ClassesRoot.CreateSubKey(Command);
                if (regcmd != null)
                    regcmd.SetValue("", path + " %1");
            }
            catch (Exception ex)
            {
                host.ThrowException(ex);
            }
            finally
            {
                if (regmenu != null)
                    regmenu.Close();
                if (regcmd != null)
                    regcmd.Close();
            }
        }

        /// <summary>
        /// Removes a entry from the contextmenu.
        /// </summary>
        void RemoveFromContextmenue()
        {
            try
            {
                RegistryKey reg = Registry.ClassesRoot.OpenSubKey(Command);
                if (reg != null)
                {
                    reg.Close();
                    Registry.ClassesRoot.DeleteSubKey(Command);
                }
                reg = Registry.ClassesRoot.OpenSubKey(MenuName);
                if (reg != null)
                {
                    reg.Close();
                    Registry.ClassesRoot.DeleteSubKey(MenuName);
                }
            }
            catch (Exception ex)
            {
                host.ThrowException(ex);
            }
        }

        /// <summary>
        /// Checks if the a entry was added to the contextmenu.
        /// </summary>
        /// <returns></returns>
        static bool IsRegistryKeySet()
        {
            if(Registry.ClassesRoot.OpenSubKey(Command) != null)
                return true;
            return false;
        }
    }
}
